<template>
  <div class="readBook" v-if="bookshelfSet" :style="{backgroundColor:bookshelfSet.backgroundColor}">
    <div class="navbar" v-show="showbar">
      <i class="icon icon-back" @click="$router.go(-1)"></i>
      <div class="title">{{bookinfo.name}}</div>
    </div>
    <div class="chapterName">
      {{currentRead.contentName}}
    </div>
    <div class="content" v-if="content.length" :class="{horizontal:bookshelfSet.currentPageTurn === 1}" @click="TapContent($event)" ref="content" >
      <div class="bookinfo"  v-if="showBookInfo">
        <div class="cover">
          <img :src="bookinfo.bookSourceUrl + bookinfo.coverUrl" alt="">
        </div>
        <div class="title">{{bookinfo.name}}</div>
        <div class="author">{{bookinfo.author}}</div>
        <div class="lastUptime">{{bookinfo.lastUpdateTime}}</div>
        <div class="desc">{{bookinfo.intro}}</div>
      </div>
      <template >
        <div class="chapter" :style="bookshelfSet" v-for="chapter,num in content" :key="num">
          <div class="title">{{chapter.contentName}}</div>
          <div v-html="chapter.content" class="novelContent"></div>
        </div>
      </template>
    </div>
    <Loading v-if="!content.length || isLoading" />
    <div class="pagination" v-if="bookshelfSet.currentPageTurn === 1">
      {{this.currentPage + 1}}/ {{this.totalPage}}
    </div>
    <div class="tabbar" v-show="showbar">
      <div class="bar"><i class="icon icon-catalog" @click="catalog"></i></div>
      <div class="bar"><i class="icon icon-moon" @click="changeTheme"></i></div>
      <div class="bar"><i class="icon icon-set" @click="set"></i></div>
      <div class="setting" v-show="showSetting">
        <div class="fontsize">
          <i class="icon icon-font-"></i>
          <Slider v-model="bookshelfSet.fontSize" @input="$store.commit('LOCAL', { bookshelfSet })" :step="1" :min="14" :max="20" />
          <i class="icon icon-fontadd"></i>
        </div>
        <div class="bg">
          <div class="bgItem" v-for="item,i in bgcolorS[theme]" :key="i" :style="{backgroundColor:item}" @click="changeColor(i)" :class="{active : currentColor === i}">

          </div>
        </div>
        <div class="pageTurn" @click="changeTurn">
          <div :class="{active:bookshelfSet.currentPageTurn === 0}">上下滑动</div>
          <div :class="{active:bookshelfSet.currentPageTurn === 1}">左右滑动</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import Slider from '@/components/slide'
import { throttle } from '@/utils/help'
export default {
  name: 'ReadBook',
  components: { Slider },
  data (){
    return {
      showBookInfo: false, // 是否显示书籍信息
      currentPage: 0, // 左右滑动的当前页数
      totalPage: 0, // 总共页数
      currentColor: 0, // 当前小说bg
      bgcolorS: {
        light: ['#cad9e8', '#d1edd1', '#e6e6e6', '#dccca9'],
        dark: ['#1f1d2a', '#291d1d', '#38344a', '#000000']
      },
      showbar: false,
      showSetting: false,
      timer: null, // 页面滚动的定时器
      isLoading: false,
      pre: false, // 是否为左右滑动的上一章
      currentRead:{
        locate: 0
      } // 默认为0

    }
  },
  async mounted (){
    // 获取本地存储的书架设置
    this.$store.commit('LOCAL', { bookshelfSet: undefined })
    this.init(this.source)
  },
  methods: {
    // 初始化书籍信息,章节列表,展示目录
    async init (source){
      if (this.pre) return
      if (source.indexOf('.html') > -1) {
        // 获取文章内容
        await this.$store.dispatch('content', { source, replace: true })
        const index = source.lastIndexOf('/')
        source = source.slice(0, index)
        this.showBookInfo = false
      } else {
        // 获取书籍介绍信息
        await this.$store.dispatch('bookinfo', source)
        this.showBookInfo = true
        const { bookSourceUrl, nextChapterUrl } = this.bookinfo
        source = bookSourceUrl + nextChapterUrl
        await this.$store.dispatch('content', { source })
      }
      if (this.bookshelfSet.currentPageTurn === 0) this.$refs.content.addEventListener('scroll', this.onscroll, false)
      // 隐藏目录
      this.$store.commit('SHOWCATALOG', '-101%')
      // 初始化当前阅读章节
      this.currentRead = Object.assign(this.currentRead, this.content[0])
      // 获取总页数
      this.w = document.documentElement.clientWidth
      // 左右滑动容器的序列号
      let contentChildIndex = 0
      if (this.showBookInfo) contentChildIndex = 1
      const totalWidth = this.$refs.content.children[contentChildIndex].getBoundingClientRect().width
      this.totalPage = Math.ceil(totalWidth / this.w)
      // 如果不是上一页,就清空当前页数
      if (!this.pre){
        this.bookshelfSet.transform = 'translateX(0)'
        this.bookshelfSet.transition = 'none'
        this.currentPage = 0
      }
    },
    // 修改读书背景
    changeColor (i){
      this.currentColor = i
      this.bookshelfSet.backgroundColor = this.bgcolorS[this.theme][i]
      // 存储书架设置
      const bookshelfSet = this.bookshelfSet
      this.$store.commit('LOCAL', { bookshelfSet })
    },
    // 修改滑动方式
    async changeTurn (e){
      const source = this.currentRead.currentChapterUrl
      if (e.target.innerText === '上下滑动') {
        this.bookshelfSet.currentPageTurn = 0
        this.bookshelfSet.transform = 'translateX(0)'
        this.bookshelfSet.transition = 'none'
      }
      if (e.target.innerText === '左右滑动') {
        this.bookshelfSet.currentPageTurn = 1
        await this.$router.push({ name: 'ReadBook', query: { source } })
        await this.$store.dispatch('content', { source, replace: true })
        const totalWidth = this.$refs.content.children[0].getBoundingClientRect().width
        this.totalPage = Math.ceil(totalWidth / this.w)
      }
      // 存储书架设置
      const bookshelfSet = this.bookshelfSet
      this.$store.commit('LOCAL', { bookshelfSet })
    },
    // 屏幕点击区域判断
    TapContent:throttle(function (e){
      const { clientX, clientY } = e
      const w = document.documentElement.clientWidth
      const h = document.documentElement.clientHeight
      this.w = w
      if (this.showCatalog === 0) {
        this.catalog()
        return
      }
      if (clientX > w / 3 && clientX < w / 3 * 2 && clientY > h / 4 && clientY < h / 4 * 3){
        this.showbar = !this.showbar
        this.showSetting = false
      } else if (clientX > w / 2){
        if (this.bookshelfSet.currentPageTurn === 1){
          this.translate(1)
          this.showBookInfo = false
        } else if (this.bookshelfSet.currentPageTurn === 0){
          // 向下滑动一页
          this.scrollTo(1, 300)
        }
      } else if (clientX < w / 2){
        if (this.bookshelfSet.currentPageTurn === 1){
          this.translate(-1)
        } else if (this.bookshelfSet.currentPageTurn === 0){
          // 向上滑动一页
          this.scrollTo(-1, 300)
        }
      }
    }, 320),
    // 上下滑动
    scrollTo (dir, time = 300){
      if (this.timer) clearInterval(this.timer)
      let h = document.documentElement.clientHeight - 60
      const step = h / time * 13 * dir
      const ele = this.$refs.content
      const top = ele.scrollTop
      if (top < h && dir === -1) h = top
      this.timer = setInterval(() => {
        ele.scrollTop += step
        if (ele.scrollTop === top) {
          console.log('滚动到底部')
          return clearInterval(this.timer)
        }
        if (Math.abs(top - ele.scrollTop) >= h) clearInterval(this.timer)
      }, 13)
    },
    // 左右滑动
    async translate (dir, time = 200){
      const { nextChapterUrl, preChapterUrl, bookSourceUrl } = this.content[0]
      // 默认滑动动画样式 all .2s ease-in-out
      this.bookshelfSet.transition = `all ${time / 1000}s ease-in-out`
      if (dir < 0 && this.currentPage === 0){
        // 加载上一章
        this.pre = true
        const source = bookSourceUrl + preChapterUrl
        await this.$router.push({ name: 'ReadBook', query: { source } })
        await this.$store.dispatch('content', { source, replace: true })
        const totalWidth = this.$refs.content.children[0].getBoundingClientRect().width
        this.totalPage = Math.ceil(totalWidth / this.w)
        this.currentPage = this.totalPage
        this.bookshelfSet.transition = 'none'
        // 初始化当前阅读章节
        this.currentRead = Object.assign(this.currentRead, this.content[0])
      }
      if (dir > 0 && this.currentPage === this.totalPage - 1){
        // 加载下一章
        this.showBookInfo = false
        this.pre = false
        const source = bookSourceUrl + nextChapterUrl
        this.$router.push({ name: 'ReadBook', query: { source } })
        await this.$store.dispatch('content', { source, replace: true })
        this.currentPage = -1
        const totalWidth = this.$refs.content.children[0].getBoundingClientRect().width
        this.totalPage = Math.ceil(totalWidth / this.w)
        this.bookshelfSet.transition = 'none'
        // 初始化当前阅读章节
        this.currentRead = Object.assign(this.currentRead, this.content[0])
      }
      this.currentPage += dir
      // 章节内容偏移量
      const x = this.currentPage * -1 * 100
      this.bookshelfSet.transform = `translateX(${x}vw)`
      // 存储书架设置
      const bookshelfSet = this.bookshelfSet
      this.$store.commit('LOCAL', { bookshelfSet })
    },
    // 监听滚动
    onscroll:throttle(function (e){
      const _this = this.$refs.content
      let index = 0
      let currentRead = {}

      // 判断滚轮的进度
      for (let i = 0; i < _this.children.length; i++){
        const child = _this.children[i]
        if (child.classList.contains('chapter')){
          if (_this.scrollTop - child.offsetTop > -_this.offsetHeight &&
          _this.scrollTop - child.offsetTop < child.offsetHeight
          ){
            currentRead.locate = _this.scrollTop - child.offsetTop

            currentRead = Object.assign(currentRead, this.content[index])
          }
          index++
        }
      }
      this.currentRead = currentRead
      console.log(_this.scrollHeight, _this.scrollTop, _this.offsetHeight)
      if (_this.scrollHeight <= _this.scrollTop + _this.offsetHeight + 50){
        console.log('到底部')
        _this.removeEventListener('scroll', this.onscroll)
        this.nextPage()
      }
    }, 50),
    // 上下翻页中的下一章加载
    async nextPage (){
      const lastContent = this.content[this.content.length - 1]
      const source = lastContent.bookSourceUrl + lastContent.nextChapterUrl
      this.isLoading = true
      await this.$store.dispatch('content', { source })
      if (this.bookshelfSet.currentPageTurn === 0) this.$refs.content.addEventListener('scroll', this.onscroll, false)
      this.isLoading = false
    },
    // 章节目录显示隐藏
    catalog (){
      const current = this.showCatalog === 0 ? '-101%' : 0
      this.$store.commit('SHOWCATALOG', current)
    },
    // 修改网站主题
    changeTheme (){
      const theme = this.theme === 'light' ? 'dark' : 'light'
      this.$store.commit('LOCAL', { theme })
      this.changeColor(0)
      // 将主题颜色变量设置好
      const style = this.themes[theme]
      for (const colorName in style){
        document.body.style.setProperty(colorName, style[colorName])
      }
    },
    // 设置的显示隐藏
    set (){
      this.showSetting = !this.showSetting
    }

  },
  computed: {
    ...mapState({
      showCatalog : state => state.novel.showCatalog,
      bookinfo: state => state.novel.bookinfo,
      content: state => state.novel.content,
      theme: state => state.user.theme,
      themes: state => state.user.themes,
      bookshelfSet: state => state.user.bookshelfSet
    }),
    source (){
      return this.$route.query.source
    }
  },
  watch: {
    source (val){
      this.init(val)
    }
  }

}
</script>

<style lang="less" scoped>
.readBook{
  min-height: 100vh;
}
.navbar{
  z-index: 10;
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  height: 2.5em;
  line-height: 2.5;
  padding: 0 1.5em;
  background-color: var(--main-darken-bg);
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--icon-color);
  .icon{
    font-size: 1.2em;
    width: 15%;
  }
  .title{
    width: 85%;
    text-align: center;
    text-indent: -7.5%;
    font-size: 1em;
  }
}
.chapterName{
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  font-size: .5rem;
  line-height: 1.5rem;
  color: var(--font-color);

  z-index: 5;
}

.content{
  padding: 1.5rem;
  width: calc(100vw - 3rem);
  position: fixed;
  top: 1.5rem;
  height: calc(100vh - 1.5rem);
  overflow-y: auto;
  overflow-x: hidden;
  line-height: 2;
  color: var(--font-color);
  .bookinfo{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    color: var(--font-color);
    min-height: 100vh;
    padding: 1.5rem;
    &>div{
      margin-bottom: 2em;
    }
    .cover{
      width: 35%;
      border-radius: .4em;
      overflow: hidden;
      img{
        width: 100%;
      }
    }
    .title{
      font-size: 1.5em;
    }
    .author{
      font-size: 1.2em;
    }
    .lastUptime{
      font-size: 1em;
    }
    .desc{
      font-size: .7em;
      line-height: 2;
    }
  }
  .chapter{
    .title{
      font-size: 1.8em;
      line-height: 3;
    }
    .novelContent{

    }
  }
}
.horizontal{
  padding: 1.5rem;
  width: auto;
  position: fixed;
  top: 1.5rem;
  height: calc(100vh - 4rem);
  line-height: 2;
  color: var(--font-color);
  columns: 100vw;
  column-gap: 3rem;
}
.pagination{
  position: fixed;
  bottom: 0;left: 0rem 0;
  height: 1rem;
  line-height: 1rem;
  font-size: .4rem;
  color: var(--font-color);
}
.tabbar{
  z-index: 10;
  position: fixed;
  left: 0;
  bottom: 0;
  right: 0;
  height: 3em;
  padding: 0 1.5em;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: var(--main-darken-bg);
  .bar{
    width: 18%;
    text-align: center;
    color: var(--icon-color);
    font-size: 1.2em;
    line-height: 3/1.2em;
  }
  .setting{
    position: fixed;
    left: 0;
    right: 0;
    bottom: 3em;
    padding: 0 1.5em;
    color: var(--icon-color);
    background-color: var(--main-darken-bg);
    .fontsize,.bg,.pageTurn{
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 3em;
      .van-slider{
        margin: 0 1.5em;
      }
      .icon{
        font-size: 1.5em;
      }
    }
    .bg{
      height: 3em;
      .bgItem{
        width: 20%;
        height: 1.5em;
      }
      .active{
        border: 1px solid var(--font-active-color);
      }
    }
    .pageTurn{
      display: flex;
      height: 3em;
      div{
        border-radius: .3em;
        padding: .23em .5em
      }
      .active{
         border:1px solid var(--font-active-color);
      }
    }

  }
}
</style>>
